//StateNode.java
package controllers.Astar;

import java.util.ArrayList;

import core.game.Observation;
import core.game.StateObservation;
import ontology.Types;
import tools.Vector2d;

public class StateNode {
    public StateObservation state;
    public StateNode fatherNode;
    public Types.ACTIONS lastAction;
    public int H;
    public int G;
    public int F;

    public StateNode(StateObservation state, StateNode fatherNode, Types.ACTIONS lastAction) {
        this.state = state;
        this.fatherNode = fatherNode;
        this.lastAction = lastAction;
        this.G = calcG();
        this.H = calcH();
        this.F = calcF();
    }

    private int L1(Vector2d vector, Vector2d refVector) {
        return (int) (Math.abs(vector.x-refVector.x)+Math.abs(vector.y-refVector.y));
    }

    public int calcG()
    {
        if (fatherNode==null) return 0;
        return fatherNode.G + 50;
    }

    public int calcH() {
        if (state.getGameWinner()== Types.WINNER.PLAYER_WINS) return -30000;
        else if (state.getGameWinner()==Types.WINNER.PLAYER_LOSES) return 30000;
        ArrayList<Observation>[] fixedPositions = state.getImmovablePositions();
        ArrayList<Observation>[] movingPositions = state.getMovablePositions();
        Vector2d goalpos = new Vector2d();
        for (ArrayList<Observation> fixedPos : fixedPositions){
            if(fixedPos.isEmpty())break;
            int iType = fixedPos.get(0).itype;
            switch (iType){
                case 7:
                    goalpos = fixedPos.get(0).position;
                    break;
            }
        }
        Vector2d npcpos = state.getAvatarPosition();
        if (state.getAvatarType()==1)
        {
            Vector2d keypos = movingPositions[0].get(0).position;
//            if (movingPositions.length>1) {
//                for (int i = 0; i<movingPositions[1].size(); i++) {
//                    if(movingPositions[1].get(i).position==keypos) return 30000;
//                }
//            }
            return L1(keypos, npcpos)+L1(keypos, goalpos);
        }
        else
        {
            return L1(npcpos, goalpos);
        }
    }

    public int calcF()
    {
        return this.G+this.H;
    }
}
